int scan(struct token* t);

struct ASTnode* mkastnode(int op, int type, struct ASTnode* left, struct ASTnode* mid, struct ASTnode* right, int intvalue);
struct ASTnode* mkastleaf(int op, int type, int intvalue);
struct ASTnode* mkastunary(int op, int type, struct ASTnode* left, int intvalue); // make a unary node: only a child

struct ASTnode* binexpr(int ptp); //return an AST tree whose root is a binary operator. parameter ptp is the previous token's precedence. 

void genpreamble();
void genpostamble();
void genfreeregs();
void genprintint(int reg);
void genglobsym(int id);
int genAST(struct ASTnode* n, int reg, int parentASTop); // generate assembly code recursively.


void freeall_registers(void);
void cgpreamble();
int cgload(int value);
int cgadd(int r1, int r2);
int cgsub(int r1, int r2);
int cgmul(int r1, int r2);
int cgdiv(int r1, int r2);
void cgprintint(int r);
int cgloadint(int value, int type);
int cgloadglob(int id);
int cgstorglob(int r, int id);
void cgglobsym(int id);
int cgequal(int r1, int r2);
int cgnotequal(int r1, int r2);
int cglessthan(int r1, int r2);
int cggreaterthan(int r1, int r2);
int cglessequal(int r1, int r2);
int cggreaterequal(int r1, int r2);
int cgcompare_and_set(int ASTop, int r1, int r2);
int cgcompare_and_jump(int ASTop, int r1, int r2, int label);
void cglabel(int l);
void cgjump(int l);
void cgfuncpostamble();
void cgfuncpreamble(char *name);
int cgwiden(int r, int oldtype, int newtype);


struct ASTnode* compound_statement(void); // parse a compound statement and return its AST


void match(int t, const char* what);
void semi(void);
void ident(void);
void lbrace(void);
void rbrace(void);
void lparen(void);
void rparen(void);
void fatal(const char* s);
void fatals(const char* s1, const char* s2);
void fatald(const char* s, int d);
void fatalc(const char* s, int c);


int findglob(char* s);
int addglob(char* name, int type, int stype);

void var_declaration(void);
struct ASTnode* function_declaration(void);


int type_compatible(int *left, int *right, int onlyright);



